<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html id="htmlId">
<head>
    <title>Coverage Report :: Level</title>
    <style type="text/css">
        @import "../../.css/coverage.css";
    </style>
</head>

<body>
<div class="header"></div>

<div class="content">
    <div class="breadCrumbs">
        [ <a href="../../index.html">all classes</a> ]
        [ <a href="../index.html">nl.tudelft.jpacman.level</a> ]
    </div>

    <h1>Coverage Summary for Class: Level (nl.tudelft.jpacman.level)</h1>

    <table class="coverageStats">

        <tr>
            <th class="name">Class</th>
            <th class="coverageStat
">
                Method, %
            </th>
            <th class="coverageStat
">
                Line, %
            </th>
        </tr>
        <tr>
            <td class="name">Level</td>
            <td class="coverageStat">
  <span class="percent">
    0%
  </span>
                <span class="absValue">
    (0/ 15)
  </span>
            </td>
            <td class="coverageStat">
  <span class="percent">
    0%
  </span>
                <span class="absValue">
    (0/ 105)
  </span>
            </td>
        </tr>
        <tr>
            <td class="name">Level$NpcMoveTask</td>
            <td class="coverageStat">
  <span class="percent">
    0%
  </span>
                <span class="absValue">
    (0/ 2)
  </span>
            </td>
            <td class="coverageStat">
  <span class="percent">
    0%
  </span>
                <span class="absValue">
    (0/ 8)
  </span>
            </td>
        </tr>
        <tr>
            <td class="name"><strong>total</strong></td>
            <td class="coverageStat">
  <span class="percent">
    0%
  </span>
                <span class="absValue">
    (0/ 17)
  </span>
            </td>
            <td class="coverageStat">
  <span class="percent">
    0%
  </span>
                <span class="absValue">
    (0/ 113)
  </span>
            </td>
        </tr>
    </table>

    <br/>
    <br/>


    <div class="sourceCode"><i>1</i>&nbsp;package nl.tudelft.jpacman.level;
        <i>2</i>&nbsp;
        <i>3</i>&nbsp;import java.util.ArrayList;
        <i>4</i>&nbsp;import java.util.HashMap;
        <i>5</i>&nbsp;import java.util.HashSet;
        <i>6</i>&nbsp;import java.util.List;
        <i>7</i>&nbsp;import java.util.Map;
        <i>8</i>&nbsp;import java.util.Map.Entry;
        <i>9</i>&nbsp;import java.util.Set;
        <i>10</i>&nbsp;import java.util.concurrent.Executors;
        <i>11</i>&nbsp;import java.util.concurrent.ScheduledExecutorService;
        <i>12</i>&nbsp;import java.util.concurrent.TimeUnit;
        <i>13</i>&nbsp;
        <i>14</i>&nbsp;import nl.tudelft.jpacman.board.Board;
        <i>15</i>&nbsp;import nl.tudelft.jpacman.board.Direction;
        <i>16</i>&nbsp;import nl.tudelft.jpacman.board.Square;
        <i>17</i>&nbsp;import nl.tudelft.jpacman.board.Unit;
        <i>18</i>&nbsp;import nl.tudelft.jpacman.npc.Ghost;
        <i>19</i>&nbsp;
        <i>20</i>&nbsp;/**
        <i>21</i>&nbsp; * A level of Pac-Man. A level consists of the board with the players and the
        <i>22</i>&nbsp; * AIs on it.
        <i>23</i>&nbsp; *
        <i>24</i>&nbsp; * @author Jeroen Roosen
        <i>25</i>&nbsp; */
        <b class="nc"><i>26</i>&nbsp;@SuppressWarnings(&quot;PMD.TooManyMethods&quot;)</b>
        <i>27</i>&nbsp;public class Level {
        <i>28</i>&nbsp;
        <i>29</i>&nbsp; /**
        <i>30</i>&nbsp; * The board of this level.
        <i>31</i>&nbsp; */
        <i>32</i>&nbsp; private final Board board;
        <i>33</i>&nbsp;
        <i>34</i>&nbsp; /**
        <i>35</i>&nbsp; * The lock that ensures moves are executed sequential.
        <i>36</i>&nbsp; */
        <b class="nc"><i>37</i>&nbsp; private final Object moveLock = new Object();</b>
        <i>38</i>&nbsp;
        <i>39</i>&nbsp; /**
        <i>40</i>&nbsp; * The lock that ensures starting and stopping can&#39;t interfere with each
        <i>41</i>&nbsp; * other.
        <i>42</i>&nbsp; */
        <b class="nc"><i>43</i>&nbsp; private final Object startStopLock = new Object();</b>
        <i>44</i>&nbsp;
        <i>45</i>&nbsp; /**
        <i>46</i>&nbsp; * The NPCs of this level and, if they are running, their schedules.
        <i>47</i>&nbsp; */
        <i>48</i>&nbsp; private final Map&lt;Ghost, ScheduledExecutorService&gt; npcs;
        <i>49</i>&nbsp;
        <i>50</i>&nbsp; /**
        <i>51</i>&nbsp; * &lt;code&gt;true&lt;/code&gt; iff this level is currently in progress, i.e. players
        <i>52</i>&nbsp; * and NPCs can move.
        <i>53</i>&nbsp; */
        <i>54</i>&nbsp; private boolean inProgress;
        <i>55</i>&nbsp;
        <i>56</i>&nbsp; /**
        <i>57</i>&nbsp; * The squares from which players can start this game.
        <i>58</i>&nbsp; */
        <i>59</i>&nbsp; private final List&lt;Square&gt; startSquares;
        <i>60</i>&nbsp;
        <i>61</i>&nbsp; /**
        <i>62</i>&nbsp; * The start current selected starting square.
        <i>63</i>&nbsp; */
        <i>64</i>&nbsp; private int startSquareIndex;
        <i>65</i>&nbsp;
        <i>66</i>&nbsp; /**
        <i>67</i>&nbsp; * The players on this level.
        <i>68</i>&nbsp; */
        <i>69</i>&nbsp; private final List&lt;Player&gt; players;
        <i>70</i>&nbsp;
        <i>71</i>&nbsp; /**
        <i>72</i>&nbsp; * The table of possible collisions between units.
        <i>73</i>&nbsp; */
        <i>74</i>&nbsp; private final CollisionMap collisions;
        <i>75</i>&nbsp;
        <i>76</i>&nbsp; /**
        <i>77</i>&nbsp; * The objects observing this level.
        <i>78</i>&nbsp; */
        <i>79</i>&nbsp; private final Set&lt;LevelObserver&gt; observers;
        <i>80</i>&nbsp;
        <i>81</i>&nbsp; /**
        <i>82</i>&nbsp; * Creates a new level for the board.
        <i>83</i>&nbsp; *
        <i>84</i>&nbsp; * @param board
        <i>85</i>&nbsp; * The board for the level.
        <i>86</i>&nbsp; * @param ghosts
        <i>87</i>&nbsp; * The ghosts on the board.
        <i>88</i>&nbsp; * @param startPositions
        <i>89</i>&nbsp; * The squares on which players start on this board.
        <i>90</i>&nbsp; * @param collisionMap
        <i>91</i>&nbsp; * The collection of collisions that should be handled.
        <i>92</i>&nbsp; */
        <i>93</i>&nbsp; public Level(Board board, List&lt;Ghost&gt; ghosts, List&lt;Square&gt; startPositions,
        <b class="nc"><i>94</i>&nbsp; CollisionMap collisionMap) {</b>
        <b class="nc"><i>95</i>&nbsp; assert board != null;</b>
        <b class="nc"><i>96</i>&nbsp; assert ghosts != null;</b>
        <b class="nc"><i>97</i>&nbsp; assert startPositions != null;</b>
        <i>98</i>&nbsp;
        <b class="nc"><i>99</i>&nbsp; this.board = board;</b>
        <b class="nc"><i>100</i>&nbsp; this.inProgress = false;</b>
        <b class="nc"><i>101</i>&nbsp; this.npcs = new HashMap&lt;&gt;();</b>
        <b class="nc"><i>102</i>&nbsp; for (Ghost ghost : ghosts) {</b>
        <b class="nc"><i>103</i>&nbsp; npcs.put(ghost, null);</b>
        <b class="nc"><i>104</i>&nbsp; }</b>
        <b class="nc"><i>105</i>&nbsp; this.startSquares = startPositions;</b>
        <b class="nc"><i>106</i>&nbsp; this.startSquareIndex = 0;</b>
        <b class="nc"><i>107</i>&nbsp; this.players = new ArrayList&lt;&gt;();</b>
        <b class="nc"><i>108</i>&nbsp; this.collisions = collisionMap;</b>
        <b class="nc"><i>109</i>&nbsp; this.observers = new HashSet&lt;&gt;();</b>
        <b class="nc"><i>110</i>&nbsp; }</b>
        <i>111</i>&nbsp;
        <i>112</i>&nbsp; /**
        <i>113</i>&nbsp; * Adds an observer that will be notified when the level is won or lost.
        <i>114</i>&nbsp; *
        <i>115</i>&nbsp; * @param observer
        <i>116</i>&nbsp; * The observer that will be notified.
        <i>117</i>&nbsp; */
        <i>118</i>&nbsp; public void addObserver(LevelObserver observer) {
        <b class="nc"><i>119</i>&nbsp; observers.add(observer);</b>
        <b class="nc"><i>120</i>&nbsp; }</b>
        <i>121</i>&nbsp;
        <i>122</i>&nbsp; /**
        <i>123</i>&nbsp; * Removes an observer if it was listed.
        <i>124</i>&nbsp; *
        <i>125</i>&nbsp; * @param observer
        <i>126</i>&nbsp; * The observer to be removed.
        <i>127</i>&nbsp; */
        <i>128</i>&nbsp; public void removeObserver(LevelObserver observer) {
        <b class="nc"><i>129</i>&nbsp; observers.remove(observer);</b>
        <b class="nc"><i>130</i>&nbsp; }</b>
        <i>131</i>&nbsp;
        <i>132</i>&nbsp; /**
        <i>133</i>&nbsp; * Registers a player on this level, assigning him to a starting position. A
        <i>134</i>&nbsp; * player can only be registered once, registering a player again will have
        <i>135</i>&nbsp; * no effect.
        <i>136</i>&nbsp; *
        <i>137</i>&nbsp; * @param player
        <i>138</i>&nbsp; * The player to register.
        <i>139</i>&nbsp; */
        <i>140</i>&nbsp; public void registerPlayer(Player player) {
        <b class="nc"><i>141</i>&nbsp; assert player != null;</b>
        <b class="nc"><i>142</i>&nbsp; assert !startSquares.isEmpty();</b>
        <i>143</i>&nbsp;
        <b class="nc"><i>144</i>&nbsp; if (players.contains(player)) {</b>
        <b class="nc"><i>145</i>&nbsp; return;</b>
        <i>146</i>&nbsp; }
        <b class="nc"><i>147</i>&nbsp; players.add(player);</b>
        <b class="nc"><i>148</i>&nbsp; Square square = startSquares.get(startSquareIndex);</b>
        <b class="nc"><i>149</i>&nbsp; player.occupy(square);</b>
        <b class="nc"><i>150</i>&nbsp; startSquareIndex++;</b>
        <b class="nc"><i>151</i>&nbsp; startSquareIndex %= startSquares.size();</b>
        <b class="nc"><i>152</i>&nbsp; }</b>
        <i>153</i>&nbsp;
        <i>154</i>&nbsp; /**
        <i>155</i>&nbsp; * Returns the board of this level.
        <i>156</i>&nbsp; *
        <i>157</i>&nbsp; * @return The board of this level.
        <i>158</i>&nbsp; */
        <i>159</i>&nbsp; public Board getBoard() {
        <b class="nc"><i>160</i>&nbsp; return board;</b>
        <i>161</i>&nbsp; }
        <i>162</i>&nbsp;
        <i>163</i>&nbsp; /**
        <i>164</i>&nbsp; * Moves the unit into the given direction if possible and handles all
        <i>165</i>&nbsp; * collisions.
        <i>166</i>&nbsp; *
        <i>167</i>&nbsp; * @param unit
        <i>168</i>&nbsp; * The unit to move.
        <i>169</i>&nbsp; * @param direction
        <i>170</i>&nbsp; * The direction to move the unit in.
        <i>171</i>&nbsp; */
        <i>172</i>&nbsp; public void move(Unit unit, Direction direction) {
        <b class="nc"><i>173</i>&nbsp; assert unit != null;</b>
        <b class="nc"><i>174</i>&nbsp; assert direction != null;</b>
        <b class="nc"><i>175</i>&nbsp; assert unit.hasSquare();</b>
        <i>176</i>&nbsp;
        <b class="nc"><i>177</i>&nbsp; if (!isInProgress()) {</b>
        <b class="nc"><i>178</i>&nbsp; return;</b>
        <i>179</i>&nbsp; }
        <i>180</i>&nbsp;
        <b class="nc"><i>181</i>&nbsp; synchronized (moveLock) {</b>
        <b class="nc"><i>182</i>&nbsp; unit.setDirection(direction);</b>
        <b class="nc"><i>183</i>&nbsp; Square location = unit.getSquare();</b>
        <b class="nc"><i>184</i>&nbsp; Square destination = location.getSquareAt(direction);</b>
        <i>185</i>&nbsp;
        <b class="nc"><i>186</i>&nbsp; if (destination.isAccessibleTo(unit)) {</b>
        <b class="nc"><i>187</i>&nbsp; List&lt;Unit&gt; occupants = destination.getOccupants();</b>
        <b class="nc"><i>188</i>&nbsp; unit.occupy(destination);</b>
        <b class="nc"><i>189</i>&nbsp; for (Unit occupant : occupants) {</b>
        <b class="nc"><i>190</i>&nbsp; collisions.collide(unit, occupant);</b>
        <b class="nc"><i>191</i>&nbsp; }</b>
        <i>192</i>&nbsp; }
        <b class="nc"><i>193</i>&nbsp; updateObservers();</b>
        <b class="nc"><i>194</i>&nbsp; }</b>
        <b class="nc"><i>195</i>&nbsp; }</b>
        <i>196</i>&nbsp;
        <i>197</i>&nbsp; /**
        <i>198</i>&nbsp; * Starts or resumes this level, allowing movement and (re)starting the
        <i>199</i>&nbsp; * NPCs.
        <i>200</i>&nbsp; */
        <i>201</i>&nbsp; public void start() {
        <b class="nc"><i>202</i>&nbsp; synchronized (startStopLock) {</b>
        <b class="nc"><i>203</i>&nbsp; if (isInProgress()) {</b>
        <b class="nc"><i>204</i>&nbsp; return;</b>
        <i>205</i>&nbsp; }
        <b class="nc"><i>206</i>&nbsp; startNPCs();</b>
        <b class="nc"><i>207</i>&nbsp; inProgress = true;</b>
        <b class="nc"><i>208</i>&nbsp; updateObservers();</b>
        <b class="nc"><i>209</i>&nbsp; }</b>
        <b class="nc"><i>210</i>&nbsp; }</b>
        <i>211</i>&nbsp;
        <i>212</i>&nbsp; /**
        <i>213</i>&nbsp; * Stops or pauses this level, no longer allowing any movement on the board
        <i>214</i>&nbsp; * and stopping all NPCs.
        <i>215</i>&nbsp; */
        <i>216</i>&nbsp; public void stop() {
        <b class="nc"><i>217</i>&nbsp; synchronized (startStopLock) {</b>
        <b class="nc"><i>218</i>&nbsp; if (!isInProgress()) {</b>
        <b class="nc"><i>219</i>&nbsp; return;</b>
        <i>220</i>&nbsp; }
        <b class="nc"><i>221</i>&nbsp; stopNPCs();</b>
        <b class="nc"><i>222</i>&nbsp; inProgress = false;</b>
        <b class="nc"><i>223</i>&nbsp; }</b>
        <b class="nc"><i>224</i>&nbsp; }</b>
        <i>225</i>&nbsp;
        <i>226</i>&nbsp; /**
        <i>227</i>&nbsp; * Starts all NPC movement scheduling.
        <i>228</i>&nbsp; */
        <i>229</i>&nbsp; private void startNPCs() {
        <b class="nc"><i>230</i>&nbsp; for (final Ghost npc : npcs.keySet()) {</b>
        <b class="nc"><i>231</i>&nbsp; ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();</b>
        <i>232</i>&nbsp;
        <b class="nc"><i>233</i>&nbsp; service.schedule(new NpcMoveTask(service, npc),</b>
        <b class="nc"><i>234</i>&nbsp; npc.getInterval() / 2, TimeUnit.MILLISECONDS);</b>
        <i>235</i>&nbsp;
        <b class="nc"><i>236</i>&nbsp; npcs.put(npc, service);</b>
        <b class="nc"><i>237</i>&nbsp; }</b>
        <b class="nc"><i>238</i>&nbsp; }</b>
        <i>239</i>&nbsp;
        <i>240</i>&nbsp; /**
        <i>241</i>&nbsp; * Stops all NPC movement scheduling and interrupts any movements being
        <i>242</i>&nbsp; * executed.
        <i>243</i>&nbsp; */
        <i>244</i>&nbsp; private void stopNPCs() {
        <b class="nc"><i>245</i>&nbsp; for (Entry&lt;Ghost, ScheduledExecutorService&gt; entry : npcs.entrySet()) {</b>
        <b class="nc"><i>246</i>&nbsp; ScheduledExecutorService schedule = entry.getValue();</b>
        <b class="nc"><i>247</i>&nbsp; assert schedule != null;</b>
        <b class="nc"><i>248</i>&nbsp; schedule.shutdownNow();</b>
        <b class="nc"><i>249</i>&nbsp; }</b>
        <b class="nc"><i>250</i>&nbsp; }</b>
        <i>251</i>&nbsp;
        <i>252</i>&nbsp; /**
        <i>253</i>&nbsp; * Returns whether this level is in progress, i.e. whether moves can be made
        <i>254</i>&nbsp; * on the board.
        <i>255</i>&nbsp; *
        <i>256</i>&nbsp; * @return &lt;code&gt;true&lt;/code&gt; iff this level is in progress.
        <i>257</i>&nbsp; */
        <i>258</i>&nbsp; public boolean isInProgress() {
        <b class="nc"><i>259</i>&nbsp; return inProgress;</b>
        <i>260</i>&nbsp; }
        <i>261</i>&nbsp;
        <i>262</i>&nbsp; /**
        <i>263</i>&nbsp; * Updates the observers about the state of this level.
        <i>264</i>&nbsp; */
        <i>265</i>&nbsp; private void updateObservers() {
        <b class="nc"><i>266</i>&nbsp; if (!isAnyPlayerAlive()) {</b>
        <b class="nc"><i>267</i>&nbsp; for (LevelObserver observer : observers) {</b>
        <b class="nc"><i>268</i>&nbsp; observer.levelLost();</b>
        <b class="nc"><i>269</i>&nbsp; }</b>
        <i>270</i>&nbsp; }
        <b class="nc"><i>271</i>&nbsp; if (remainingPellets() == 0) {</b>
        <b class="nc"><i>272</i>&nbsp; for (LevelObserver observer : observers) {</b>
        <b class="nc"><i>273</i>&nbsp; observer.levelWon();</b>
        <b class="nc"><i>274</i>&nbsp; }</b>
        <i>275</i>&nbsp; }
        <b class="nc"><i>276</i>&nbsp; }</b>
        <i>277</i>&nbsp;
        <i>278</i>&nbsp; /**
        <i>279</i>&nbsp; * Returns &lt;code&gt;true&lt;/code&gt; iff at least one of the players in this level
        <i>280</i>&nbsp; * is alive.
        <i>281</i>&nbsp; *
        <i>282</i>&nbsp; * @return &lt;code&gt;true&lt;/code&gt; if at least one of the registered players is
        <i>283</i>&nbsp; * alive.
        <i>284</i>&nbsp; */
        <i>285</i>&nbsp; public boolean isAnyPlayerAlive() {
        <b class="nc"><i>286</i>&nbsp; for (Player player : players) {</b>
        <b class="nc"><i>287</i>&nbsp; if (player.isAlive()) {</b>
        <b class="nc"><i>288</i>&nbsp; return true;</b>
        <i>289</i>&nbsp; }
        <b class="nc"><i>290</i>&nbsp; }</b>
        <b class="nc"><i>291</i>&nbsp; return false;</b>
        <i>292</i>&nbsp; }
        <i>293</i>&nbsp;
        <i>294</i>&nbsp; /**
        <i>295</i>&nbsp; * Counts the pellets remaining on the board.
        <i>296</i>&nbsp; *
        <i>297</i>&nbsp; * @return The amount of pellets remaining on the board.
        <i>298</i>&nbsp; */
        <i>299</i>&nbsp; public int remainingPellets() {
        <b class="nc"><i>300</i>&nbsp; Board board = getBoard();</b>
        <b class="nc"><i>301</i>&nbsp; int pellets = 0;</b>
        <b class="nc"><i>302</i>&nbsp; for (int x = 0; x &lt; board.getWidth(); x++) {</b>
        <b class="nc"><i>303</i>&nbsp; for (int y = 0; y &lt; board.getHeight(); y++) {</b>
        <b class="nc"><i>304</i>&nbsp; for (Unit unit : board.squareAt(x, y).getOccupants()) {</b>
        <b class="nc"><i>305</i>&nbsp; if (unit instanceof Pellet) {</b>
        <b class="nc"><i>306</i>&nbsp; pellets++;</b>
        <i>307</i>&nbsp; }
        <b class="nc"><i>308</i>&nbsp; }</b>
        <i>309</i>&nbsp; }
        <i>310</i>&nbsp; }
        <b class="nc"><i>311</i>&nbsp; assert pellets &gt;= 0;</b>
        <b class="nc"><i>312</i>&nbsp; return pellets;</b>
        <i>313</i>&nbsp; }
        <i>314</i>&nbsp;
        <i>315</i>&nbsp; /**
        <i>316</i>&nbsp; * A task that moves an NPC and reschedules itself after it finished.
        <i>317</i>&nbsp; *
        <i>318</i>&nbsp; * @author Jeroen Roosen
        <i>319</i>&nbsp; */
        <i>320</i>&nbsp; private final class NpcMoveTask implements Runnable {
        <i>321</i>&nbsp;
        <i>322</i>&nbsp; /**
        <i>323</i>&nbsp; * The service executing the task.
        <i>324</i>&nbsp; */
        <i>325</i>&nbsp; private final ScheduledExecutorService service;
        <i>326</i>&nbsp;
        <i>327</i>&nbsp; /**
        <i>328</i>&nbsp; * The NPC to move.
        <i>329</i>&nbsp; */
        <i>330</i>&nbsp; private final Ghost npc;
        <i>331</i>&nbsp;
        <i>332</i>&nbsp; /**
        <i>333</i>&nbsp; * Creates a new task.
        <i>334</i>&nbsp; *
        <i>335</i>&nbsp; * @param service
        <i>336</i>&nbsp; * The service that executes the task.
        <i>337</i>&nbsp; * @param npc
        <i>338</i>&nbsp; * The NPC to move.
        <i>339</i>&nbsp; */
        <b class="nc"><i>340</i>&nbsp; NpcMoveTask(ScheduledExecutorService service, Ghost npc) {</b>
        <b class="nc"><i>341</i>&nbsp; this.service = service;</b>
        <b class="nc"><i>342</i>&nbsp; this.npc = npc;</b>
        <i>343</i>&nbsp; }
        <i>344</i>&nbsp;
        <i>345</i>&nbsp; @Override
        <i>346</i>&nbsp; public void run() {
        <b class="nc"><i>347</i>&nbsp; Direction nextMove = npc.nextMove();</b>
        <b class="nc"><i>348</i>&nbsp; if (nextMove != null) {</b>
        <b class="nc"><i>349</i>&nbsp; move(npc, nextMove);</b>
        <i>350</i>&nbsp; }
        <b class="nc"><i>351</i>&nbsp; long interval = npc.getInterval();</b>
        <b class="nc"><i>352</i>&nbsp; service.schedule(this, interval, TimeUnit.MILLISECONDS);</b>
        <i>353</i>&nbsp; }
        <i>354</i>&nbsp; }
        <i>355</i>&nbsp;
        <i>356</i>&nbsp; /**
        <i>357</i>&nbsp; * An observer that will be notified when the level is won or lost.
        <i>358</i>&nbsp; *
        <i>359</i>&nbsp; * @author Jeroen Roosen
        <i>360</i>&nbsp; */
        <i>361</i>&nbsp; public interface LevelObserver {
        <i>362</i>&nbsp;
        <i>363</i>&nbsp; /**
        <i>364</i>&nbsp; * The level has been won. Typically the level should be stopped when
        <i>365</i>&nbsp; * this event is received.
        <i>366</i>&nbsp; */
        <i>367</i>&nbsp; void levelWon();
        <i>368</i>&nbsp;
        <i>369</i>&nbsp; /**
        <i>370</i>&nbsp; * The level has been lost. Typically the level should be stopped when
        <i>371</i>&nbsp; * this event is received.
        <i>372</i>&nbsp; */
        <i>373</i>&nbsp; void levelLost();
        <i>374</i>&nbsp; }
        <i>375</i>&nbsp;}
    </div>
</div>

<div class="footer">

    <div style="float:right;">generated on 2023-04-25 16:45</div>
</div>
</body>
</html>
